#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace KLib.Physics.Collisions
{
    /// <summary>
    /// An Axis-Aligned Bounding-Box (AABB)
    /// </summary>
    public class AABB
    {
        #region Fields
        /// <summary>
        /// The Minimum value of the AABB
        /// </summary>
        public Vector2 Min;

        /// <summary>
        /// The Maximum value of the AABB
        /// </summary>
        public Vector2 Max;
        #endregion

        #region Properties
        public float Width
        {
            get { return Max.X - Min.X; }
        }

        public float Height
        {
            get { return Max.Y - Min.Y;}
        }
        #endregion
        #region Initialization

        /// <summary>
        /// Creates an Empty AABB that is undefined (describes no space)
        /// </summary>
        public AABB()
        {
            Max = Vector2.Zero;
            Min = Vector2.Zero;
        }

        /// <summary>
        /// Creates an AABB that has the min and max points specified
        /// </summary>
        /// <param name="minPnt">The minimum point of the AABB</param>
        /// <param name="maxPnt">The Maximum point of the AABB</param>
        public AABB(Vector2 minPnt, Vector2 maxPnt)
        {
            Min = minPnt;
            Max = maxPnt;
        }

        public AABB(AABB aabb)
        {
            this.Min = aabb.Min;
            this.Max = aabb.Max;
        }
        #endregion

        #region Methods
        Vector2 tmpVert;
        public void Update(Vertices vertices)
        {
            if (vertices.Count <= 0) return;
            Min = vertices[0];
            Max = Min;
            for (int i = 0; i < vertices.Count; i++)
			{
                tmpVert = vertices[i];

                if (tmpVert.X < Min.X) Min.X = tmpVert.X;
                if (tmpVert.X > Max.X) Max.X = tmpVert.X;

                if (tmpVert.Y < Min.Y) Min.Y = tmpVert.Y;
                if (tmpVert.Y > Max.Y) Max.Y = tmpVert.Y;
            }
        }
        #endregion

        #region Expansion
        /// <summary>
        /// Expands the AABB to include the point specified
        /// </summary>
        /// <param name="point">The point to expand the AABB too</param>
        public void Expand(Vector2 point)
        {
            if (point.X < Min.X) { Min.X = point.X; }
            else if (point.X > Max.X) { Max.X = point.X; }

            if (point.Y < Min.Y) { Min.Y = point.Y; }
            else if (point.Y > Max.Y) { Max.Y = point.Y; }
        }
        #endregion

        #region Collision

        /// <summary>
        /// Returns True of the point is inside of this AABB
        /// </summary>
        public bool Contains(Vector2 point)
        {
            return (point.X >= Min.X) && (point.X <= Max.X) && (point.Y >= Min.Y) && (point.Y <= Max.Y);
        }

        /// <summary>
        /// Returns True if this AABB Contains or Intersects with another AABB
        /// </summary>
        public bool Intersects(AABB box)
        {
            return (Min.X <= box.Max.X) && (Max.X >= box.Min.X) && (Min.Y <= box.Max.Y) && (Max.Y >= box.Min.Y);
        }
        #endregion
    }
}
